﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Xml.Linq;
using Novapangeia.Dominio;
using Novapangeia.RepositorioNHibernate;
using SharpArch.Data.NHibernate;

namespace Novapangeia.Negocio
{ 
    public class GerenciadorConstrucao
    {
        //Verificações de pré-requisitos para construções

        //Esses metodos verificam se o usuario atende aos
        //pre-requisitos das construções antes de disponibiliza-las
        //para execução (só existe o metodo se a construção tem pré-requisitos)

        public static bool MuralhaLiberada(Usuario u){
            if (u.tecnologias.Engenharia)
            {
                return true;
            }
            return false;
        }

        public static bool TorreLiberada(Usuario u) {
            if (u.tecnologias.Engenharia && u.construcoes.Quartel)
            {
                return true;
            }
            return false;
        }

        public static bool EstabuloLiberado(Usuario u) {
            if (u.tecnologias.Cavalaria)
            {
                return true;
            } 
            return false;
        }

        public static bool QuartelLiberado(Usuario u){
            if(u.construcoes.Armazem > 0)
            {
                return true;
            }
            return false;
        }


        //Verificações de custos
        //Verifica se o usuario pode pagar pelos custos da construção

        public static bool podePagarMuralha(Usuario u){
            return u.PodePagar(CustoConstrução.CustoRelativo(Constantes.CUSTOBASEMURALHA, (int)(u.construcoes.Muralha+1)));
        }

        public static bool podePagarArmazem(Usuario u)
        {
            return u.PodePagar(CustoConstrução.CustoRelativo(Constantes.CUSTOBASEARMAZEM, (int)(u.construcoes.Armazem + 1)));
        }

        public static bool podePagarMercado(Usuario u){
            return u.PodePagar(CustoConstrução.CustoRelativo(Constantes.CUSTOBASEMERCADO, (int)(u.construcoes.Mercado + 1)));
        }

        public static bool podePagarMina(Usuario u){
            return u.PodePagar(CustoConstrução.CustoRelativo(Constantes.CUSTOBASEMINA, (int)(u.construcoes.Mina + 1)));
        }

        public static bool podePagarFazenda(Usuario u){
            return u.PodePagar(CustoConstrução.CustoRelativo(Constantes.CUSTOBASEFAZENDA, (int)(u.construcoes.Fazenda + 1)));
        }

        public static bool podePagarSerraria(Usuario u){
            return u.PodePagar(CustoConstrução.CustoRelativo(Constantes.CUSTOBASESERRARIA, (int)(u.construcoes.Serraria + 1)));
        }

        public static bool podePagarTorres(Usuario u)
        {
            return u.PodePagar(CustoConstrução.CustoRelativo(Constantes.CUSTOBASETORRES, (int)(u.construcoes.Torres + 1)));
        }

        public static bool podePagarQuartel(Usuario u){
            return u.PodePagar(Constantes.CUSTOQUARTEL);
        }

        public static bool podePagarEstabulo(Usuario u){
            return u.PodePagar(Constantes.CUSTOESTABULO);
        }
        
        
        //Retorna os custos das contruções
        public static CustoConstrução CustoMuralha(Usuario u)
        {
            return CustoConstrução.CustoRelativo(Constantes.CUSTOBASEMURALHA, (int)(u.construcoes.Muralha + 1));
        }

        public static CustoConstrução CustoArmazem(Usuario u)
        {
            return CustoConstrução.CustoRelativo(Constantes.CUSTOBASEARMAZEM, (int)(u.construcoes.Armazem + 1));
        }

        public static CustoConstrução CustoMercado(Usuario u)
        {
            return CustoConstrução.CustoRelativo(Constantes.CUSTOBASEMERCADO, (int)(u.construcoes.Mercado + 1));
        }

        public static CustoConstrução CustoMina(Usuario u)
        {
            return CustoConstrução.CustoRelativo(Constantes.CUSTOBASEMINA, (int)(u.construcoes.Mina + 1));
        }

        public static CustoConstrução CustoFazenda(Usuario u)
        {
            return CustoConstrução.CustoRelativo(Constantes.CUSTOBASEFAZENDA, (int)(u.construcoes.Fazenda + 1));
        }

        public static CustoConstrução CustoSerraria(Usuario u)
        {
            return CustoConstrução.CustoRelativo(Constantes.CUSTOBASESERRARIA, (int)(u.construcoes.Serraria + 1));
        }

        public static CustoConstrução CustoTorres(Usuario u)
        {
            return CustoConstrução.CustoRelativo(Constantes.CUSTOBASETORRES, (int)(u.construcoes.Torres + 1));
        }

        public static CustoConstrução CustoQuartel(Usuario u)
        {
            return Constantes.CUSTOQUARTEL;
        }

        public static CustoConstrução CustoEstabulo(Usuario u)
        {
            return Constantes.CUSTOESTABULO;
        }

        private static bool Atualizar(Usuario usuario)
        {
            using (UnitOfWork.Start())
            {
                RepositorioUsuario repositorioUsuario = new RepositorioUsuario();
                repositorioUsuario.SaveOrUpdate(usuario);

                RepositorioEstoque repositorioEstoque = new RepositorioEstoque();
                repositorioEstoque.SaveOrUpdate(usuario.recursos);

                RepositorioConstrucao repositorioConstrucao = new RepositorioConstrucao();
                repositorioConstrucao.SaveOrUpdate(usuario.construcoes);

                //return sqlHelper.SaveChanges();
            }
            return true;
        }

        //Construções e Pagamentos

        //Esses metodos setam efetivamente as construções e
        //e debitam os custos dos recursos do usuario.

        public static bool construirMuralha(Usuario u) 
        {
            if (podePagarMuralha(u) && MuralhaLiberada(u))
            {
                int n = (int) u.construcoes.Muralha;
                CustoConstrução c = CustoConstrução.CustoRelativo(Constantes.CUSTOBASEMURALHA, n + 1);
                u.DebitarRecursos(c);
                u.construcoes.Muralha++;
                return Atualizar(u);
            }
            return false;
        }

        public static bool construirMercado(Usuario u)
        {
            if (podePagarMercado(u))
            {
                int n = (int) u.construcoes.Mercado;
                CustoConstrução c = CustoConstrução.CustoRelativo(Constantes.CUSTOBASEMERCADO, n + 1);
                u.DebitarRecursos(c);
                u.construcoes.Mercado++;
                return Atualizar(u);
            }
            return false;
        }

        public static bool construirMina(Usuario u)
        {
            if (podePagarMina(u))
            {
                int n = (int) u.construcoes.Mina;
                CustoConstrução c = CustoConstrução.CustoRelativo(Constantes.CUSTOBASEMINA, n + 1);
                u.DebitarRecursos(c);
                u.construcoes.Mina++;
                return Atualizar(u);
            }
            return false;
        }

        public static bool construirFazenda(Usuario u)
        {
            if (podePagarFazenda(u))
            {
                int n = (int) u.construcoes.Fazenda;
                CustoConstrução c = CustoConstrução.CustoRelativo(Constantes.CUSTOBASEFAZENDA, n + 1);
                u.DebitarRecursos(c);
                u.construcoes.Fazenda++;
                return Atualizar(u);
            }
            return false;
        }

        public static bool construirSerraria(Usuario u)
        {
            if (podePagarSerraria(u))
            {
                int n = (int) u.construcoes.Serraria;
                CustoConstrução c = CustoConstrução.CustoRelativo(Constantes.CUSTOBASESERRARIA, n + 1);
                u.DebitarRecursos(c);
                u.construcoes.Serraria++;
                return Atualizar(u);
            }
            return false;
        }


        public static bool construirTorres(Usuario u)
        {
            if (podePagarTorres(u) && TorreLiberada(u))
            {
                int n = (int)u.construcoes.Torres;
                CustoConstrução c = CustoConstrução.CustoRelativo(Constantes.CUSTOBASETORRES, n + 1);
                u.DebitarRecursos(c);
                u.construcoes.Torres++;
                return Atualizar(u);
            }
            return false;
        }

        public static bool construirArmazem(Usuario u)
        {
            if (podePagarArmazem(u))
            {
                int n = (int)u.construcoes.Armazem;
                CustoConstrução c = CustoConstrução.CustoRelativo(Constantes.CUSTOBASEARMAZEM, n + 1);
                u.DebitarRecursos(c);
                u.construcoes.Armazem++;
                return Atualizar(u);
            }
            return false;
        }

        public static bool construirQuartel(Usuario u)
        {
            if (podePagarQuartel(u) && QuartelLiberado(u))
            {
                u.DebitarRecursos(Constantes.CUSTOQUARTEL);
                u.construcoes.Quartel = true;
                return Atualizar(u);
            }
            return false;
        }

        public static bool construirEstabulo(Usuario u)
        {
            if (podePagarEstabulo(u) && EstabuloLiberado(u))
            {
                u.DebitarRecursos(Constantes.CUSTOESTABULO);
                u.construcoes.Estabulo = true;
                return Atualizar(u);
            }
            return false;
        }
    }
}
